package model;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;

/**
 * Publicly accessible struct representing a stack of cards on the table. 
 * This is to be used only in TableModel.
 * These stacks are not to be used for player's hands. Use the PlayerHand class instead for that.
 */
public class CardStack {
    /** Contents of the stack.  */
    private Stack<Card> cards;
    /** x coordinate of center of the bottom card on the stack */
    public int x;
    /** y coordinate of center of the bottom card on the stack */
    public int y; 
    /** size of stack */
    private int size;
    /** true if the stack is flipped upside down */
    public boolean flipped;
    

    
    public CardStack(int x, int y) {
        this.cards = new Stack<Card>();
        this.x=x;
        this.y=y;
        this.size = 0;
        this.flipped = false;
    }
    
    /**
     * Checks to see if card stack invariant still true
     * @return
     */
    public void checkRep()
    {
    	//System.out.println("check rep " + cards.size() + " " + this.size);
    	assert cards.size() == this.size;
    }
    
    public Card get(int i)
    {
    	return cards.get(i);
    }
    
    public Stack<Card> getAll()
    {
    	return cards;
    }
    
    public boolean isEmpty()
    {
    	return cards.isEmpty();
    }
    
    public boolean move(int x, int y)
    {
    	this.x = x;
    	this.y = y;
    	return true;
    }
    
    public int getSize()
    {
    	return this.size;
    }
    
    public Card push(Card card)
    {
    	this.size++;
    	return cards.push(card);
    }
    
    public Card pop()
    {
    	this.size--;
    	return cards.pop();
    }
    
    public boolean addAll(CardStack many)
    {
    	this.size += many.getSize();
    	return cards.addAll(many.cards);
    }
    
    public boolean remove(Card c)
    {
    	this.size -= 1;
    	return cards.remove(c);
    }
    
    public boolean removeAll(CardStack many)
    {
    	this.size -= many.getSize();
    	return cards.removeAll(many.cards);
    }
    
    public boolean contains(Card card)
    {
    	return cards.contains(card);
    }

    public boolean isTopHighlighted()
    {
    	return cards.get(cards.size()-1).isHighlighted();
    
    }
    
    public boolean isHighlighted()
    {
    	for (Card card: cards)
    		if (!card.isHighlighted())
	    		return false;
    	return true;
    }
    
    public void highlightStack()
    {
    	
    	for (Card card: cards)
    	{
    		card.highlightedTrue();
    	}
    	
    }
    
    public void unhighlightStack()
    {
    	
    	for (Card card: cards)
    	{
    		card.highlightedFalse();
    	}
    }
    
    public void shuffle()
    {
    	Random ran = new Random();
    	
    	for (int i = this.size-1; i > 0; i--)
    	{
    		
    		//generate random number from 0 to i
    		int ranIndex = ran.nextInt(i);
    		
    		//swap contents
    		Card front = cards.get(ranIndex);
    		Card back = cards.get(i);
    		//Card tmp = front;
    		
    		cards.set(ranIndex, back);
    		cards.set(i, front);

    		
    	}
    	
    }
    
    public void flip() {
    	flipped = !flipped;
    }
}